/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */

'use strict';

const startVideo = document.getElementById('startVideo');
const callVideo = document.getElementById('callVideo');
const startDisplay = document.getElementById('startDisplay');
const callDisplay = document.getElementById('callDisplay');
const hangup = document.getElementById('hangup');

callVideo.disabled = true;
callDisplay.disabled = true;
hangup.disabled = true;

startVideo.onclick = startVideoFunc;
callVideo.onclick = callVideoFunc;
startDisplay.onclick = startDisplayFunc;
callDisplay.onclick = callDisplayFunc;
hangup.onclick = hangupFunc;

const localVideo = document.querySelector('video#local_video');
const localDisplay = document.querySelector('video#local_display');
const remoteVideo = document.querySelector('video#remote_video');
const remoteDisplay = document.querySelector('video#remote_display');

const localAudio = document.querySelector('audio#local_audio');
const remoteAudio = document.querySelector('audio#remote_audio');

let localStream;
let localAudioTrack;
let localVideoTrack;
let localDisplayTrack;

localStream = new MediaStream();

let localPeer;
let remotePeer;

// Create an RTCPeerConnection via the polyfill.
const servers = null;

console.log("remoteVideo: ", isEmpty(remoteVideo.srcObject));

localPeer = new RTCPeerConnection(servers);
remotePeer = new RTCPeerConnection(servers);
remotePeer.ontrack = (e) => {
  console.log("====ontrack", e.streams.length);
  
  let stream = e.streams[0];
  let len = stream.getTracks().length
  
  let tempStream = new MediaStream();
  if (len == 1) {
    tempStream.addTrack(stream.getTracks()[0]);
    remoteVideo.srcObject = tempStream;
    console.log('remotePeer.ontrack: received remote video stream');
  } else if (len == 2) {
    tempStream.addTrack(stream.getTracks()[1]);
    remoteDisplay.srcObject = tempStream;
    console.log('remotePeer.ontrack: received remote display stream');
  }
};
localPeer.onicecandidate = iceCallbackLocal;
remotePeer.onicecandidate = iceCallbackRemote;
console.log('remoteVideo: created local and remote peer connection objects');

// ================= Start Video
function startVideoFunc() {
  console.log('Requesting local stream');
  startVideo.disabled = true;
  
  // local stream
  navigator.mediaDevices
    .getUserMedia({ audio: true, video: true })
    .then(stream => {
      console.log('Received local stream');
      
      localVideoTrack = stream.getVideoTracks()[0];
      let videoStream = new MediaStream();
      videoStream.addTrack(localVideoTrack);
      localVideo.srcObject = videoStream;
      
      // localAudioTrack = stream.getAudioTracks()[0];
      // let audioStream = new MediaStream();
      // audioStream.addTrack(localAudioTrack);
      // localAudio.srcObject = audioStream;

      localStream.addTrack(localVideoTrack);
      callVideo.disabled = false;
    })
    .catch(e => console.log('getUserMedia() error: ', e));
}

function callVideoFunc() {
  callVideo.disabled = true;
  console.log('Starting video transfer');
    
  localPeer.addTrack(localVideoTrack, localStream);
  localPeer.createOffer().then(gotDescriptionLocal, onCreateSessionDescriptionError);  
  
  hangup.disabled = false;
}

// =============== Start Display
function startDisplayFunc() {
  console.log('Requesting display stream');
  startDisplay.disabled = true;
  
  // display stream
  navigator.mediaDevices
    .getDisplayMedia({ video: true })
    .then(stream => {
      console.log('Requested display stream');
      
      localDisplayTrack = stream.getVideoTracks()[0];
      let displayStream = new MediaStream();
      displayStream.addTrack(localDisplayTrack);
      localDisplay.srcObject = displayStream;
      
      localStream.addTrack(localDisplayTrack);      
      callDisplay.disabled = false;
    }, error => {
      console.log("Unable to acquire screen capture", error);
    });
}

function callDisplayFunc() {
  callDisplay.disabled = true;
  console.log('Starting display transfer');
  
  console.log("===callDisplayFunc:localPeer", localPeer.getLocalStreams().length)
  console.log("===callDisplayFunc:localStream", localStream.getTracks().length)
  localPeer.addTrack(localDisplayTrack, localStream);
  console.log("===callDisplayFunc", localPeer.getLocalStreams().length)
  
  localPeer.createOffer().then(gotDescriptionLocal, onCreateSessionDescriptionError);
  
  hangup.disabled = false;
}

function hangupFunc() {
  console.log('Ending calls');
  
  localPeer.close();
  remotePeer.close();  
  localPeer = null;
  remotePeer = null;
  
  hangup.disabled = true;
  startVideo.disabled = false;
  startDisplay.disabled = false;
}

function onCreateSessionDescriptionError(error) {
  console.log(`Failed to create session description: ${error.toString()}`);
}

function gotDescriptionLocal(desc) {
  localPeer.setLocalDescription(desc);
  console.log(`Offer from localPeer\n${desc.sdp}`);
  remotePeer.setRemoteDescription(desc);
  remotePeer.createAnswer().then(gotDescriptionRemote, onCreateSessionDescriptionError);
}

function gotDescriptionRemote(desc) {
  remotePeer.setLocalDescription(desc);
  console.log(`Answer from remotePeer\n${desc.sdp}`);
  localPeer.setRemoteDescription(desc);
}

function iceCallbackLocal(event) {
  handleCandidate(event.candidate, remotePeer, 'remotePeer: ', 'local');
}

function iceCallbackRemote(event) {
  handleCandidate(event.candidate, localPeer, 'remotePeer: ', 'remote');
}

function handleCandidate(candidate, dest, prefix, type) {
  dest.addIceCandidate(candidate)
      .then(onAddIceCandidateSuccess, onAddIceCandidateError);
  console.log(`${prefix}New ${type} ICE candidate: ${candidate ? candidate.candidate : '(null)'}`);
}

function onAddIceCandidateSuccess() {
  console.log('AddIceCandidate success.');
}

function onAddIceCandidateError(error) {
  console.log(`Failed to add ICE candidate: ${error.toString()}`);
}

function isEmpty(obj) {
  return (obj === undefined) || (obj == null)
}